package com.uinnova.product.eam.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.binary.core.exception.BinaryException;
import com.binary.core.exception.MessageException;
import com.binary.core.util.BinaryUtils;
import com.google.common.collect.Lists;
import com.uinnova.product.eam.base.exception.ValidException;
import com.uinnova.product.eam.base.util.EamUtil;
import com.uinnova.product.eam.comm.bean.AppSquareConfigVO;
import com.uinnova.product.eam.comm.bean.CatalogDto;
import com.uinnova.product.eam.comm.model.es.AppSquareConfig;
import com.uinnova.product.eam.model.AppSquareConfigBo;
import com.uinnova.product.eam.model.dto.AppSquareConfigVo;
import com.uinnova.product.eam.model.enums.AppSquareTypeEnum;
import com.uinnova.product.eam.model.enums.BasicSettingSortEnum;
import com.uinnova.product.eam.model.enums.ModelEnum;
import com.uinnova.product.eam.service.AppSquareConfigSvc;
import com.uinnova.product.eam.service.ICISwitchSvc;
import com.uinnova.product.eam.service.IEamCIClassApiSvc;
import com.uinnova.product.eam.service.asset.ArchitectureAssetSvc;
import com.uinnova.product.eam.service.asset.AssetDetailAttrConfSvc;
import com.uinnova.product.eam.service.asset.AssetListAttrConfSvc;
import com.uinnova.product.eam.service.es.AppSquareConfigDao;
import com.uinnova.product.vmdb.provider.ci.bean.CcCiClassInfo;
import com.uino.api.client.cmdb.IDataSetApiSvc;
import com.uino.api.client.permission.IRoleApiSvc;
import com.uino.api.client.permission.IUserApiSvc;
import com.uino.bean.cmdb.base.LibType;
import com.uino.bean.cmdb.base.dataset.OperateType;
import com.uino.bean.permission.base.SysRole;
import com.uino.bean.permission.base.SysUser;
import com.uino.bean.permission.business.UserInfo;
import com.uino.dao.util.ESUtil;
import com.uino.util.sys.BeanUtil;
import com.uino.util.sys.CommonFileUtil;
import com.uino.util.sys.SysUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author bingshen
 * @Classname AppSquareConfigSvcImpl
 * @Date 2022/5/25 14:43
 */
@Service
@Slf4j
public class AppSquareConfigSvcImpl implements AppSquareConfigSvc {

    @Autowired
    private AppSquareConfigDao basicOperationSettingDao;

    @Autowired
    private IDataSetApiSvc dataSetApiSvc;

    @Resource
    AssetListAttrConfSvc listAttrConfSvc;

    @Resource
    AssetDetailAttrConfSvc detailAttrConfSvc;

    @Resource
    IRoleApiSvc roleApiSvc;

    @Resource
    IUserApiSvc userApiSvc;
    @Resource
    ArchitectureAssetSvc architectureAssetSvc;

    @Resource
    IEamCIClassApiSvc ciClassApiSvc;

    @Resource
    private ICISwitchSvc iciSwitchSvc;

    @Override
    public Long saveOrUpdate(AppSquareConfigBo basicSettingBo) {
        // 校验必填项
        String check = this.check(basicSettingBo);
        if(!BinaryUtils.isEmpty(check)){
            throw new BinaryException(check);
        }
        if (!CollectionUtils.isEmpty(basicSettingBo.getCatalogList())) {
            for (CatalogDto catalogDto : basicSettingBo.getCatalogList()) {
                if (catalogDto.getCatalogId() == null) {
                    catalogDto.setCatalogId(ESUtil.getUUID());
                }
            }
        }
        AppSquareConfig insertEntity = new AppSquareConfig();
        BeanUtils.copyProperties(basicSettingBo, insertEntity);
        insertEntity.setDomainId(SysUtil.getCurrentUserInfo().getDomainId());
        AppSquareConfig oldConfig = null;
        if (BinaryUtils.isEmpty(insertEntity.getId())) {
//            List<AppSquareConfig> listByCdt = basicOperationSettingDao.getListByCdt(new AppSquareConfig());

            long uuid = ESUtil.getUUID();
            insertEntity.setId(uuid);
            insertEntity.setIsInit(1);
            /*if (!CollectionUtils.isEmpty(listByCdt)) {
                insertEntity.setSort(listByCdt.size() + 1.0);
            } else {
                insertEntity.setSort(1.0);
            }*/
            insertEntity.setCreator(SysUtil.getCurrentUserInfo().getLoginCode());
            insertEntity.setCreateTime(ESUtil.getNumberDateTime());
            // 新建架构资产卡片校验分类是否存在默认属性（不存在添加处理分类数据 创建时间、修改时间、资产状态）
            if (AppSquareTypeEnum.ASSET.getType().equals(insertEntity.getClassification())||AppSquareTypeEnum.PANORAMA.getType().equals(insertEntity.getClassification())) {
                CcCiClassInfo classByCode = ciClassApiSvc.getCIClassByCodes(insertEntity.getClassCode());
                architectureAssetSvc.classAndCiProcessingByClassId(Lists.newArrayList(classByCode.getCiClass().getId()));
            }
        } else {
            // 架构资产更新分类信息，清空列表及内容配置
            oldConfig = basicOperationSettingDao.getById(insertEntity.getId());
            if (AppSquareTypeEnum.ASSET.getType().equals(insertEntity.getClassification())) {
                if (!BinaryUtils.isEmpty(oldConfig) && !BinaryUtils.isEmpty(oldConfig.getClassCode())
                        && !oldConfig.getClassCode().equals(insertEntity.getClassCode())) {
                    listAttrConfSvc.delListAttrByAppSquareConfId(insertEntity.getId());
                    detailAttrConfSvc.deleteDetailAttrByAppSquareConfId(insertEntity.getId());
                }
            }
        }
        insertEntity.setSort(this.sortConfig(oldConfig, insertEntity.getAssetType()));
        return basicOperationSettingDao.saveOrUpdate(insertEntity);
    }

    private Double sortConfig(AppSquareConfig oldConf, Integer assetType){
        List<AppSquareConfig> configList = basicOperationSettingDao.getListByCdt(new AppSquareConfig());
        if(CollectionUtils.isEmpty(configList)){
            return 1.0;
        }
        if(oldConf == null){
            return configList.size() + 1.0;
        }
        if(assetType == null || assetType.equals(oldConf.getAssetType())){
            return oldConf.getSort();
        }
        Double max = configList.stream().map(AppSquareConfig::getSort).max(Double::compareTo).orElse(oldConf.getSort());
        return max + 1;
    }

    private void checkNotNullAttr(AppSquareConfigBo basicSettingBo) {
        Objects.requireNonNull(basicSettingBo.getCardName(), "卡片名称不能为空");
        Objects.requireNonNull(basicSettingBo.getClassification(), "所属分类不能为空");
        Objects.requireNonNull(basicSettingBo.getPictureInfo(), "图片信息不能为空");
        Objects.requireNonNull(basicSettingBo.getStatus(), "状态不能为空");
    }

    @Override
    public AppSquareConfigVO getInfoById(Long id) {
        AppSquareConfigVO squareConfigVo = new AppSquareConfigVO();
        AppSquareConfig appSquareConfig = basicOperationSettingDao.getById(id);
        if (!BinaryUtils.isEmpty(appSquareConfig) &&
                !CollectionUtils.isEmpty(appSquareConfig.getRolePermission())) {
            // 资产配置
            List<JSONObject> rolePermission = appSquareConfig.getRolePermission();
            List<Long> roleIdList = new ArrayList<>();
            HashMap<Long, String> roleAuthMap = new HashMap<>();
            for (JSONObject roleJson : rolePermission) {
                JSONArray roleIds = roleJson.getJSONArray("roleId");
                String operation = roleJson.getString("operation");
                for (Object roleId : roleIds) {
                    if (!BinaryUtils.isEmpty(roleId)) {
                        roleIdList.add(Long.valueOf(roleId.toString()));
                        roleAuthMap.put(Long.valueOf(roleId.toString()), operation);
                    }
                }
            }
            if (!CollectionUtils.isEmpty(roleIdList)) {
                List<SysRole> sysRoles = roleApiSvc.getRoleListByIds(roleIdList, SysUtil.getCurrentUserInfo().getDomainId());
                ArrayList<JSONObject> roleAuthInfo = new ArrayList<>();
                for (SysRole sysRole : sysRoles) {
                    JSONObject roleAuth = new JSONObject();
                    roleAuth.put("role", sysRole);
                    roleAuth.put("operation", roleAuthMap.get(sysRole.getId()));
                    roleAuthInfo.add(roleAuth);
                }
                squareConfigVo.setRoleAuthInfo(roleAuthInfo);
            }
        }
        if (!BinaryUtils.isEmpty(appSquareConfig)) {
            BeanUtil.copyProperties(appSquareConfig, squareConfigVo);
        }
        return squareConfigVo;
    }

    @Override
    public int deleteInfoById(Long id) {
        Integer result = basicOperationSettingDao.deleteById(id);
        List<SortBuilder<?>> sorts = new ArrayList<>();
        sorts.add(SortBuilders.fieldSort("sort").order(SortOrder.ASC));
        List<AppSquareConfig> sortList = basicOperationSettingDao.getSortListByCdt(new AppSquareConfig(), sorts);
        for (int i = 0; i < sortList.size(); i++) {
            sortList.get(i).setSort(i + 1.0);
        }
        basicOperationSettingDao.saveOrUpdateBatch(sortList);
        return result;
    }

    @Override
    public List<AppSquareConfig> getListInfo(AppSquareConfigBo basicSettingBo) {
        List<SortBuilder<?>> sorts = new ArrayList<>();
        SysUser user = SysUtil.getCurrentUserInfo();
        if (StringUtils.isNotBlank(basicSettingBo.getSortField())) {
            if (basicSettingBo.getSortField().equals(BasicSettingSortEnum.CARD_NAME.field)) {
                sorts.add(SortBuilders.fieldSort(BasicSettingSortEnum.CARD_NAME.field + ".keyword").order(basicSettingBo.getIdAsc() ? SortOrder.ASC : SortOrder.DESC));
                sorts.add(SortBuilders.fieldSort("createTime").order(SortOrder.DESC));
            } else if (basicSettingBo.getSortField().equals(BasicSettingSortEnum.CLASSIFICATION.field)) {
                sorts.add(SortBuilders.fieldSort(BasicSettingSortEnum.CLASSIFICATION.field + ".keyword").order(basicSettingBo.getIdAsc() ? SortOrder.ASC : SortOrder.DESC));
                sorts.add(SortBuilders.fieldSort("createTime").order(SortOrder.DESC));
            } else if (basicSettingBo.getSortField().equals(BasicSettingSortEnum.STATUS.field)) {
                sorts.add(SortBuilders.fieldSort(BasicSettingSortEnum.STATUS.field + ".keyword").order(basicSettingBo.getIdAsc() ? SortOrder.ASC : SortOrder.DESC));
                sorts.add(SortBuilders.fieldSort("createTime").order(SortOrder.DESC));
            }
        } else {
            sorts.add(SortBuilders.fieldSort("sort").order(SortOrder.ASC));
        }
        AppSquareConfig queryCdt = new AppSquareConfig();
        if (basicSettingBo.getIsInit() != null) {
            queryCdt.setIsInit(basicSettingBo.getIsInit());
        }
        if (basicSettingBo.getClassification() != null) {
            queryCdt.setClassification(basicSettingBo.getClassification());
        }
        Set<String> classCodes = new HashSet<>();
        List<AppSquareConfig> result = basicOperationSettingDao.getSortListByCdt(queryCdt, sorts);
        for (AppSquareConfig appSquareConfig : result) {
            if (BinaryUtils.isEmpty(appSquareConfig.getGroupSort())) {
                appSquareConfig.setGroupSort(appSquareConfig.getSort());
            }
            if(!BinaryUtils.isEmpty(appSquareConfig.getClassCode())){
                classCodes.add(appSquareConfig.getClassCode());
            }
            if(BinaryUtils.isEmpty(appSquareConfig.getCardName()) || BinaryUtils.isEmpty(appSquareConfig.getClassification())
                    || BinaryUtils.isEmpty(appSquareConfig.getCatalogList())||BinaryUtils.isEmpty(appSquareConfig.getCardType())){
                continue;
            }
            if (appSquareConfig.getIsInit() == 0 && appSquareConfig.getClassification().equals("1") && appSquareConfig.getCatalogList() == null && appSquareConfig.getCardType().equals("multiDiagram")) {
                List<CatalogDto> catalogDtoList = new ArrayList<>();
                LinkedHashMap initCatalogMap = JSON.parseObject(appSquareConfig.getConfigure(), LinkedHashMap.class);
                LinkedHashMap configMap = JSON.parseObject(initCatalogMap.get("config").toString(), LinkedHashMap.class);
                for (Object initCatalog : initCatalogMap.keySet()) {
                    if (initCatalog.equals("config")) {
                        continue;
                    }
                    CatalogDto catalogDto = new CatalogDto();
                    catalogDto.setCatalogId(ESUtil.getUUID());
                    catalogDto.setCatalogName(configMap.get(initCatalog).toString());
                    catalogDto.setDiagramId(initCatalogMap.get(initCatalog).toString());
                    catalogDtoList.add(catalogDto);
                }
                appSquareConfig.setCatalogList(catalogDtoList);
            }
        }
        Map<String, Long> countMap = iciSwitchSvc.getCiCountMap(classCodes, user.getLoginCode(), LibType.DESIGN);
        for (AppSquareConfig each : result) {
            if(!BinaryUtils.isEmpty(each.getClassCode()) && AppSquareTypeEnum.ASSET.getType().equals(each.getClassification())){
                each.setCiCount(countMap.getOrDefault(each.getClassCode(), 0L));
            }
        }
        // 过滤资产用户没有权限的卡片
        UserInfo userInfo = userApiSvc.getUserInfoByLoginCode(user.getLoginCode());
        Set<SysRole> roles = userInfo.getRoles();
        Set<String> roleNames = roles.stream().map(sysRole -> sysRole.getRoleName()).collect(Collectors.toSet());
        // 管理员不进行过滤
        if (!(roleNames.contains("admin") || roleNames.contains("架构资产管理员"))) {
            Set<Long> currUserRoleIds = roles.stream().map(sysRole -> sysRole.getId()).collect(Collectors.toSet());
            Iterator<AppSquareConfig> iterator = result.iterator();
            while (iterator.hasNext()) {
                AppSquareConfig next = iterator.next();
                if (!BinaryUtils.isEmpty(next) && (AppSquareTypeEnum.ASSET.getType().equals(next.getClassification())
                        ||AppSquareTypeEnum.PANORAMA.getType().equals(next.getClassification())||AppSquareTypeEnum.ANALYSIS.getType().equals(next.getClassification()))) {
                    boolean flog = false;
                    List<Long> roleIdList = new ArrayList<>();
                    if (!BinaryUtils.isEmpty(next.getRolePermission())) {
                        List<JSONObject> rolePermission = next.getRolePermission();
                        for (JSONObject roleJson : rolePermission) {
                            JSONArray roleIds = roleJson.getJSONArray("roleId");
                            for (Object roleId : roleIds) {
                                if (!BinaryUtils.isEmpty(roleId)) {
                                    roleIdList.add(Long.valueOf(roleId.toString()));
                                }
                            }
                        }
                        for (Long id : roleIdList) {
                            if (currUserRoleIds.contains(id)) {
                                flog = true;
                                break;
                            }
                        }
                    }else {
                        // 兼容专题分析存量数据未配置角色权限都显示
                        flog = true;
                    }
                    if (!flog) {
                        iterator.remove();
                    }
                }
            }
        }
        return result;
    }

    @Override
    public List<AppSquareConfig> getListInfoByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        List<AppSquareConfig> result = basicOperationSettingDao.getListByQuery(QueryBuilders.termsQuery("id", ids));
        UserInfo userInfo = userApiSvc.getUserInfoByLoginCode(SysUtil.getCurrentUserInfo().getLoginCode());
        Set<SysRole> roles = userInfo.getRoles();
        Set<String> roleNames = roles.stream().map(sysRole -> sysRole.getRoleName()).collect(Collectors.toSet());
        // 非管理员过滤停用的卡片
        if (!(roleNames.contains("admin"))) {
            result = result.stream().filter(appSquareConfig -> BinaryUtils.isEmpty(appSquareConfig.getStatus()) || appSquareConfig.getStatus().equals(1)).collect(Collectors.toList());
        }
        return result;
    }

    @Override
    public List<AppSquareConfig> getByIdsWithoutAuth(Set<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        List<AppSquareConfig> result = basicOperationSettingDao.getListByQuery(QueryBuilders.termsQuery("id", ids));
        return CollectionUtils.isEmpty(result)?Collections.emptyList():result;
    }

    @Override
    public Integer batchSaveInfos(List<AppSquareConfigBo> list) {
        List<AppSquareConfig> appSquareConfigList = EamUtil.copy(list, AppSquareConfig.class);
        Integer result = basicOperationSettingDao.saveOrUpdateBatch(appSquareConfigList);
        return result;
    }

    @Override
    public ResponseEntity<byte[]> exportConfigInitData() {
        AppSquareConfig appSquareConfig = new AppSquareConfig();
        appSquareConfig.setIsInit(0);

        List<AppSquareConfig> exportConfigList = basicOperationSettingDao.getListByCdt(appSquareConfig);

        String configListString = JSON.toJSONString(exportConfigList);

        File file = new File(basicOperationSettingDao.getIndex() + ".json");
        try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
            IOUtils.write(configListString, fileOutputStream, String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            log.error("制品文件生成失败", e);
        }
        ResponseEntity<byte[]> responseEntity = returnRes(file);
        //FileUtils.deleteQuietly(file);
        return responseEntity;
    }

    @Override
    public Boolean reductInitData(Long cardId) {
        List<AppSquareConfig> data = CommonFileUtil.getData("/initdata/uino_eam_square_config.json", AppSquareConfig.class);
        List<AppSquareConfig> reductionCardInfos = data.stream().filter(item -> item.getId().equals(cardId)).collect(Collectors.toList());
        if (reductionCardInfos != null && reductionCardInfos.size() > 0) {
            AppSquareConfig appSquareConfig = reductionCardInfos.get(0);
            AppSquareConfig sortAppSquareConfig = basicOperationSettingDao.getById(cardId);
            appSquareConfig.setSort(sortAppSquareConfig.getSort());
            basicOperationSettingDao.deleteById(cardId);
            basicOperationSettingDao.saveOrUpdate(appSquareConfig);
            return true;
        }
        return false;
    }

    @Override
    public AppSquareConfigVo getDataByCardId(Long cardId) {
        List<JSONObject> dataSet = dataSetApiSvc.findDataSet("", false, "", new ArrayList<>());
        AppSquareConfig appSquareConfig = getInfoById(cardId);
        String configure = appSquareConfig.getConfigure();
        if (StringUtils.isBlank(configure)) {
            return new AppSquareConfigVo();
        }
        JSONObject jsonObject = JSON.parseObject(configure);
        if (jsonObject.get("pattern") == null) {
            AppSquareConfigVo appSquareConfigVo = new AppSquareConfigVo();
            appSquareConfigVo.setCardName(appSquareConfig.getCardName());
            return appSquareConfigVo;
        }
        String pattern = jsonObject.get("pattern").toString();
        Object dataConfig = jsonObject.get("dataConfig");
        if (StringUtils.isNotBlank(pattern) && dataConfig != null) {
            List<JSONObject> dataListInfo = new ArrayList<>();
            if (pattern.equals(ModelEnum.OBJECT_ANALYSIS.value)) {
                String preString = dataConfig.toString().substring(1);
                String lastString = preString.substring(0, preString.length() - 1);
                String[] dataIds = lastString.split(",");
                List<String> dataList = Arrays.asList(dataIds);
                List<JSONObject> result = dataSet.stream().filter(item -> dataList.contains(item.get("id").toString())).collect(Collectors.toList());
                if (result == null || result.size() < 1) {
                    throw new ValidException("数据集不存在，请前往[基础操作]页面重新配置该卡片使用的数据集");
                }
                List<JSONObject> sortResult = sortConfigList(dataList, result);
                AppSquareConfigVo appSquareConfigVo = new AppSquareConfigVo();
                appSquareConfigVo.setMode(pattern);
                appSquareConfigVo.setCardName(appSquareConfig.getCardName());
                if (jsonObject.get("showApiDetail") != null) {
                    appSquareConfigVo.setShowApiDetail(Boolean.valueOf(jsonObject.get("showApiDetail").toString()));
                }
                for (JSONObject object : sortResult) {
                    JSONObject storeInfo = new JSONObject();
                    storeInfo.put("id", object.get("id"));
                    storeInfo.put("name", object.get("name"));
                    dataListInfo.add(storeInfo);
                }
                appSquareConfigVo.setStoreList(dataListInfo);
                return appSquareConfigVo;
            } else {
                List<JSONObject> result = dataSet.stream().filter(item -> item.get("id").toString().equals(dataConfig.toString())).collect(Collectors.toList());
                AppSquareConfigVo appSquareConfigVo = new AppSquareConfigVo();
                appSquareConfigVo.setMode(pattern);
                appSquareConfigVo.setCardName(appSquareConfig.getCardName());
                if (jsonObject.get("showApiDetail") != null) {
                    appSquareConfigVo.setShowApiDetail(Boolean.valueOf(jsonObject.get("showApiDetail").toString()));
                }
                for (JSONObject object : result) {
                    JSONObject storeInfo = new JSONObject();
                    storeInfo.put("id", object.get("id"));
                    storeInfo.put("name", object.get("name"));
                    dataListInfo.add(storeInfo);
                }
                appSquareConfigVo.setStoreList(dataListInfo);
                return appSquareConfigVo;
            }
        }
        return new AppSquareConfigVo();
    }

    private List<JSONObject> sortConfigList(List<String> dataList, List<JSONObject> result) {
        List<JSONObject> sortResultList = new ArrayList<>();
        Map<String, JSONObject> configList = result.stream().collect(Collectors.toMap(item -> item.get("id").toString(), item -> item));
        for (String cardId : dataList) {
            JSONObject jsonObject = configList.get(cardId);
            sortResultList.add(jsonObject);
        }
        return sortResultList;
    }

    @Override
    public List<JSONObject> getFilterDataSet() {
        List<JSONObject> dataSet = dataSetApiSvc.findDataSet("", false, "", new ArrayList<>());
        List<JSONObject> result = new ArrayList<>();
        if(CollectionUtils.isEmpty(dataSet)){
            return result;
        }
        for (JSONObject each : dataSet) {
            if(each.getInteger("shareLevel").equals(OperateType.Invisible.getCode()) ||
                    CollectionUtils.isEmpty(each.getJSONArray("nodes"))){
                continue;
            }
            result.add(each);
        }
        return result;
    }

    @Override
    public boolean dragSort(Long cardId, Integer sortNum) {
        List<AppSquareConfig> appSquareConfigList = basicOperationSettingDao.getListByCdt(new AppSquareConfig());
        List<AppSquareConfig> sortAppSquareConfigList = appSquareConfigList.stream().filter(item -> !item.getId().equals(cardId)).sorted(Comparator.comparing(AppSquareConfig::getSort)).collect(Collectors.toList());
        for (int i = 0; i < sortAppSquareConfigList.size(); i++) {
            sortAppSquareConfigList.get(i).setSort(Double.valueOf(i) + Double.valueOf(1));
        }

        for (int i = 0; i < sortAppSquareConfigList.size(); i++) {
            if (sortNum == i + 1) {
                for (int j = sortNum - 1; j < sortAppSquareConfigList.size(); j++) {
                    sortAppSquareConfigList.get(j).setSort(sortAppSquareConfigList.get(j).getSort() + 1);
                }
                break;
            }
        }
        AppSquareConfig dragCard = getInfoById(cardId);
        dragCard.setSort(Double.valueOf(sortNum));
        sortAppSquareConfigList.add(dragCard);
        basicOperationSettingDao.saveOrUpdateBatch(sortAppSquareConfigList);
        return true;
    }
    @Override
    public boolean groupDragSort(Long cardId, Integer sortNum) {
        AppSquareConfig byId = basicOperationSettingDao.getById(cardId);
        List<AppSquareConfig> appSquareConfigList = basicOperationSettingDao.getListByCdt(new AppSquareConfig());
        List<AppSquareConfig> groupList = new ArrayList<>();
        Integer assetType = byId.getAssetType();
        if (BinaryUtils.isEmpty(assetType)) {
            assetType = 1;
        }
        for (AppSquareConfig appSquareConfig : appSquareConfigList) {
            if ("1".equals(appSquareConfig.getClassification())||"3".equals(appSquareConfig.getClassification())||"6".equals(appSquareConfig.getClassification())) {
                if (BinaryUtils.isEmpty(appSquareConfig.getAssetType())) {
                    appSquareConfig.setAssetType(1);
                }
                if (appSquareConfig.getAssetType().equals(assetType)) {
                    if (BinaryUtils.isEmpty(appSquareConfig.getGroupSort())) {
                        appSquareConfig.setGroupSort(appSquareConfig.getSort());
                    }
                    groupList.add(appSquareConfig);
                }
            }
        }
        List<AppSquareConfig> sortAppSquareConfigList = groupList.stream().filter(item -> !item.getId().equals(cardId))
                .sorted(Comparator.comparing(AppSquareConfig::getGroupSort)).collect(Collectors.toList());
        for (int i = 0; i < sortAppSquareConfigList.size(); i++) {
            sortAppSquareConfigList.get(i).setGroupSort(Double.valueOf(i) + Double.valueOf(1));
        }

        for (int i = 0; i < sortAppSquareConfigList.size(); i++) {
            if (sortNum == i + 1) {
                for (int j = sortNum - 1; j < sortAppSquareConfigList.size(); j++) {
                    sortAppSquareConfigList.get(j).setGroupSort(sortAppSquareConfigList.get(j).getGroupSort() + 1);
                }
                break;
            }
        }
        byId.setGroupSort(Double.valueOf(sortNum));
        sortAppSquareConfigList.add(byId);
        basicOperationSettingDao.saveOrUpdateBatch(sortAppSquareConfigList);
        return true;
    }


    @Override
    public void refreshData() {
        AppSquareConfig appSquareConfig = new AppSquareConfig();
        appSquareConfig.setClassification("2");
        List<AppSquareConfig> refreshList = basicOperationSettingDao.getListByCdt(appSquareConfig);
        for (AppSquareConfig squareConfig : refreshList) {
            String configure = squareConfig.getConfigure();
            JSONObject jsonObject = JSONObject.parseObject(configure);
            if (jsonObject.get("pattern") != null) {
                String pattern = jsonObject.get("pattern").toString();
                if ("对象分析".equals(pattern) || "对象分析模式".equals(pattern)) {
                    jsonObject.put("pattern", ModelEnum.OBJECT_ANALYSIS.value);
                    squareConfig.setConfigure(jsonObject.toJSONString());
                }
                if ("全景平铺".equals(pattern) || "全景平铺模式".equals(pattern)) {
                    jsonObject.put("pattern", ModelEnum.PANORAMA_TILE.value);
                    squareConfig.setConfigure(jsonObject.toJSONString());
                }
            }
        }
        basicOperationSettingDao.saveOrUpdateBatch(refreshList);
    }

    @Override
    public List<JSONObject> findPlanDataSetList() {
        List<JSONObject> dataSet = dataSetApiSvc.findDataSet("", false, "", new ArrayList<>());
        if (dataSet == null || dataSet.size() <= 0) {
            return new ArrayList<>();
        }
        return dataSet.stream().filter(item -> !item.get("shareLevel").equals(0)).filter(item -> item.get("nodes") != null).collect(Collectors.toList());
    }


    private ResponseEntity<byte[]> returnRes(File file) {
        HttpHeaders headers = new HttpHeaders();
        ResponseEntity<byte[]> entity = null;
        InputStream in = null;
        try {
            in = new FileInputStream(file);
            byte[] bytes = new byte[in.available()];
            int read = in.read(bytes);
            if (read != in.available()) {
                log.info("这块不能直接判断个数,需要等待所有读取完才能比较");
            }
            headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
            entity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
        } catch (Exception e) {
            throw new MessageException(e.getMessage());
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return entity;
    }

    @Override
    public AppSquareConfig getAppSquareConfigByClassCode(String classCode) {
        BinaryUtils.checkEmpty(classCode, "分类标识");
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        query.must(QueryBuilders.termQuery("classCode.keyword", classCode));
        query.must(QueryBuilders.termQuery("classification.keyword", AppSquareTypeEnum.ASSET.getType()));
        AppSquareConfig appSquareConfig = basicOperationSettingDao.selectOne(query);
        if (BinaryUtils.isEmpty(appSquareConfig)) {
            throw new BinaryException("该分类资产配置信息不存在，请添加配置");
        }
        return appSquareConfig;
    }

    @Override
    public List<String> getExistsClassByClassification(String classification) {
        BinaryUtils.checkEmpty(classification,"卡片分类");
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        query.must(QueryBuilders.termQuery("domainId", SysUtil.getCurrentUserInfo().getDomainId()));
        query.must(QueryBuilders.termQuery("classification.keyword", classification));
        List<AppSquareConfig> list = basicOperationSettingDao.getListByQuery(query);
        List<String> classCodes = new ArrayList<>();
        for (AppSquareConfig appSquareConfig : list) {
            if (!BinaryUtils.isEmpty(appSquareConfig.getClassCode())) {
                classCodes.add(appSquareConfig.getClassCode());
            }
        }
        return classCodes;
    }

    @Override
    public String check(AppSquareConfigBo basicSettingBo) {
        // 校验必填项
        checkNotNullAttr(basicSettingBo);
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("cardName.keyword", basicSettingBo.getCardName().trim()));
        boolQueryBuilder.must(QueryBuilders.termQuery("classification.keyword", basicSettingBo.getClassification().trim()));
        if (!BinaryUtils.isEmpty(basicSettingBo.getId())) {
            boolQueryBuilder.mustNot(QueryBuilders.termQuery("id", basicSettingBo.getId()));
        }
        AppSquareConfig basicOperationSetting = basicOperationSettingDao.selectOne(boolQueryBuilder);
        boolean classFlag = !BinaryUtils.isEmpty(basicSettingBo.getClassification()) && !BinaryUtils.isEmpty(basicSettingBo.getClassCode());
        if (!BinaryUtils.isEmpty(basicOperationSetting)) {
            String errorInfo;
            switch (basicSettingBo.getClassification()) {
                case "5":
                    errorInfo = classFlag?"资产分类已存在":"资产名称已存在";
                    break;
                case "6":
                    errorInfo = classFlag?"架构全景分类已存在":"全景名称已存在";
                    break;
                default:
                    errorInfo = classFlag?"分类已存在":"名称重复";
            }
            return errorInfo;
        }
        return null;
    }

    @Override
    public Long updateBusinessDiagram(CatalogDto dto) {
        AppSquareConfig config = basicOperationSettingDao.getById(dto.getConfigId());
        if(config == null){
            return 0L;
        }
        if(CollectionUtils.isEmpty(config.getCatalogList())){
            JSONObject configure = JSON.parseObject(config.getConfigure());
            configure.put("diagramId", dto.getDiagramId());
            configure.put("dataSet", dto.isDataSet());
            config.setConfigure(configure.toJSONString());
        }else{
            for (CatalogDto each : config.getCatalogList()) {
                if(!each.getCatalogId().equals(dto.getCatalogId())){
                    continue;
                }
                each.setDiagramId(dto.getDiagramId());
                each.setDataSet(dto.isDataSet());
            }
        }
        return basicOperationSettingDao.saveOrUpdate(config);
    }

    @Override
    public List<AppSquareConfig> queryByType(List<String> classList, Integer assetType){
        Assert.notEmpty(classList, "功能类型");
        Assert.notNull(assetType, "资产类型");
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        query.must(QueryBuilders.termQuery("domainId", SysUtil.getCurrentUserInfo().getDomainId()));
        if(!CollectionUtils.isEmpty(classList)){
            query.must(QueryBuilders.termQuery("classification.keyword", classList));
        }
        if(!BinaryUtils.isEmpty(assetType)){
            query.must(QueryBuilders.termQuery("assetType", assetType));
        }
        List<AppSquareConfig> result = basicOperationSettingDao.getListByQuery(query);
        return CollectionUtils.isEmpty(result)?Collections.emptyList():result;
    }
}
